package com.tch.aop;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Enumeration;

/**
 *  使用AOP 统一处理 WEB 请求日志
 *  在方法的前后实现拦截，减少打印日志代码的冗余性的问题
 *  20210923PM
 *
 *  定义一个切面拦截 包
 */
@Aspect
@Component
@Slf4j
public class WebLogAspect {
    @Pointcut("execution(public * com.tch.controller.*.*(..))")
    public void webLog(){

    }

    /**
     * 前置通知 请求方法之前做拦截
     * @param joinPoint
     */
    @Before("webLog()")
    public void doBefore(JoinPoint joinPoint)throws Throwable{
        // 接收导请求，记录请求内容
        ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        // 记录下请求内容
        log.info("URL : "+ request.getRequestURL().toString());
        log.info("HTTP_METHOD : "+ request.getMethod());
        log.info("IP : "+ request.getRemoteAddr());
        Enumeration<String> enu = request.getParameterNames();
        while (enu.hasMoreElements()){
            String element = enu.nextElement();
            log.info("name:{},value:{}",element,request.getParameter(element));
        }
    }

    /**
     * 目标方法请求之后  打印(响应)信息
     * @param ret
     * @throws Throwable
     */
    @AfterReturning(returning="ret",pointcut = "webLog()")
    public void dpAfterReturning(Object ret)throws Throwable{
        //处理完请求， 返回内容
        log.info("RESPONSE : "+ ret);
    }
}
